package com.code.question1.impl;

import com.code.question1.base.SearchType;
import com.code.question1.base.User;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Student extends User<Student> implements Serializable {
    private static final long serialVersionUID = -7888067279068935775L;
    private String studentNo;

    public String getStudentNo() {
        return studentNo;
    }

    public void setStudentNo(String studentNo) throws StudentNoException {
        //学号校验正则
        String reg = "[1-9]\\d{9}";
        if (!studentNo.matches(reg)) {
            throw new StudentNoException("学号格式有误，请输入10位数字的学号");
        }
        this.studentNo = studentNo;
    }

    /**
     * 学生信息列表
     */
    private static Map<String, Student> studentMap = new HashMap<>();

    public Student() {
    }

    public Student(String studentNo, String name, String age) throws StudentAgeException {
        this.studentNo = studentNo;
        this.setName(name);
        this.setAge(age);
    }

    /**
     * 学生是否存在
     *
     * @param key 学号
     * @return 是否存在
     */
    public static boolean ExistsStudent(String key) {
        return studentMap.containsKey(key);
    }

    /**
     * 添加学生信息
     *
     * @param student
     * @return
     */
    @Override
    public boolean Post(Student student) {
        studentMap.put(student.getStudentNo(), student);
        return true;
    }

    /**
     * 删除学生信息
     *
     * @param key
     * @return
     */
    @Override
    public boolean Delete(String key) {
        Student student = studentMap.remove(key);
        return null == student ? false : true;
    }
    /**
     * 获取学生列表信息，
     * @return
     */
    @Override
    public List<Student> Get() {
        List<Student> returnStuList = new ArrayList<>();
        studentMap.keySet().stream().forEach(s -> returnStuList.add(studentMap.get(s)));
        return returnStuList;
    }
    /**
     * 获取学生列表信息，
     *
     * @param filed 查找的内容值
     * @param type  查找的类型（姓名 学号 年龄）
     * @return
     */
    @Override
    public List<Student> Get(String filed, SearchType type) {
        switch (type) {
            case No:
                return GetByStudentNo(filed);
            case Age:
                return GetByAge(filed);
            case Name:
                return GetByName(filed);
        }
        return null;
    }

    /**
     * 根据学号查找
     *
     * @param filed 查找的字符串
     * @return
     */
    private List<Student> GetByStudentNo(String filed) {
        List<Student> returnStuList = new ArrayList<>();
        studentMap.keySet().stream().filter(s -> s.contains(filed)).forEach(s -> returnStuList.add(studentMap.get(s)));
        return returnStuList;
    }

    /**
     * 通过姓名查找
     *
     * @param filed 查找的字符串
     * @return
     */
    private List<Student> GetByName(String filed) {
        List<Student> students = studentMap.values().stream().filter(student -> student.getName().contains(filed)).collect(Collectors.toList());
        return students;
    }

    /**
     * 根据年龄查找
     *
     * @param filed 查找的字符串
     * @return
     */
    private List<Student> GetByAge(String filed) {
        final int age;
        try {
            age = Integer.parseInt(filed);
        } catch (NumberFormatException ex) {
            return null;
        }
        List<Student> students = studentMap.values().stream().filter(student -> student.getAge() == age).collect(Collectors.toList());
        return students;
    }

    @Override
    public boolean Put(Student student) {
        studentMap.put(student.getStudentNo(), student);
        return true;
    }

    /**
     * 打印
     * @return
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("学号\t姓名\t年龄\n");
        studentMap.values().stream().forEach(student -> {
            sb.append(student.getStudentNo() + "\t" + student.getName() + "\t" + student.getAge() + "\n");
        });
        return sb.toString();
    }

    /**
     * 打印部分学生信息
     * @param students
     * @return
     */
    public String toString(List<Student> students) {
        StringBuilder sb = new StringBuilder();
        sb.append("学号\t姓名\t年龄\n");
        students.stream().forEach(student -> {
            sb.append(student.getStudentNo() + "\t" + student.getName() + "\t" + student.getAge() + "\n");
        });
        return sb.toString();
    }
}
